Efficient storage allocation is critical to the performance of a virtual machine system. In any file system, files are frequently created, modified and deleted. When adding data to files, storage blocks have to be allocated. In order to save resources, storage can be allocated on a need-to-use basis, a method sometimes referred to as thin provisioning. In file systems, files allocated in such a manner are referred to as sparse files. When a write operation is performed to a sparse file, blocks are allocated to store the added data.
Virtual machine “hard drives” are implemented via a file or a block device, and is usually referred to as an “image.” Conventionally, image files tend to unnecessarily inflate in volume. This is because the data blocks of an image file deleted by a virtual machine cannot be easily reused by the host of the virtual machine. The backing disk storage is unaware of the file deletion that happens in the VM. Thus, in a conventional virtual machine system, the size of the images can continue to grow, thereby eliminating a major benefit of using thin provisioning.
One conventional approach uses a utility in the virtual machine that periodically writes zeros to deallocated blocks. The hypervisor of the virtual machine system “catches” these write operations, and detects that the written blocks are zeros. The hypervisor then redirects the blocks to point to a “zero” block, which is linked to the written blocks. All of the written blocks that are linked to the “zero” block are freed and can be reused. With this approach, free blocks are regained only periodically and image files can still inflate in the interim. Further, the hypervisor needs to check all of the written blocks and compare those blocks to zero. The checking and comparing operations are not efficient and, as a result, reduce the performance of the system.